package game.adm.dao.impl;

import game.adm.dao.BetDAO;
import game.adm.dao.dto.BetDTO;
import game.adm.dao.dto.BonusDTO;
import game.adm.dao.impl.BonusDAOImpl.field;
import game.adm.struts.form.BetForm;
import game.web.base.Constants;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;

import projectx.core.base.ProjectXSystemException;
import projectx.core.dao.AbstractDAO;
import projectx.core.dao.DataAccessException;
import projectx.core.dao.ExceptionHandler;
import projectx.core.dao.impl.PreparedStatementBuilder;

public class BetDAOImpl extends AbstractDAO implements BetDAO {

	public enum field {
		betid, userid, betmethod,types,gametype,gametypename,bettype,bettypename,betmoney,bonus,betstr,betstrs,betcount,singlemoney,betno,opentime,returnpos,returnmoney,betflag,createtime,updatetime,createip,updateip,username;
	}

	public BetDAOImpl() throws ProjectXSystemException {
		super();
	}
	
	private List<BetDTO> toList(ResultSet rs) throws Exception{
		List<BetDTO> list = new ArrayList<BetDTO>();
		while (rs.next()) {
			String betid = getString(rs.getString(field.betid.ordinal()+1));
			String uid = getString(rs.getString(field.userid.ordinal()+1));
			int betmethod = rs.getInt(field.betmethod.ordinal()+1);
			String types = rs.getString(field.types.ordinal()+1);
			String gametype = rs.getString(field.gametype.ordinal()+1);
			String gametypename = rs.getString(field.gametypename.ordinal()+1);
			String bettype = rs.getString(field.bettype.ordinal()+1);
			String bettypename = rs.getString(field.bettypename.ordinal()+1);
			double betmoney = rs.getDouble(field.betmoney.ordinal()+1);
			double bonus = rs.getDouble(field.bonus.ordinal()+1);
			String betstr = rs.getString(field.betstr.ordinal()+1);
			String betstrs = rs.getString(field.betstrs.ordinal()+1);
			int betcount = rs.getInt(field.betcount.ordinal()+1);
			double singlemoney = rs.getDouble(field.singlemoney.ordinal()+1);
			String betno = rs.getString(field.betno.ordinal()+1);
			String opentime = rs.getString(field.opentime.ordinal()+1);
			double returnpos = rs.getDouble(field.returnpos.ordinal()+1);
			double returnmoney = rs.getDouble(field.returnmoney.ordinal()+1);
			int betflag = rs.getInt(field.betflag.ordinal()+1);
			String createtime = rs.getString(field.createtime.ordinal()+1);
			String updatetime = rs.getString(field.updatetime.ordinal()+1);
			String createip = getString(rs.getString(field.createip.ordinal()+1));
			String updateip = getString(rs.getString(field.updateip.ordinal()+1));
			String username = getString(rs.getString(field.username.ordinal()+1));
			BetDTO dto = new BetDTO();
			dto.setBetid(betid);
			dto.setUserid(uid);
			dto.setBetmethod(betmethod);
			dto.setTypes(types);
			dto.setGametype(gametype);
			dto.setGametypename(gametypename);
			dto.setBettype(bettype);
			dto.setBettypename(bettypename);
			dto.setBetmoney(betmoney);
			dto.setBonus(bonus);
			dto.setBetstr(betstr);
			dto.setBetstrs(betstrs);
			dto.setBetcount(betcount);
			dto.setSinglemoney(singlemoney);
			dto.setBetno(betno);
			dto.setOpentime(opentime);
			dto.setReturnpos(returnpos);
			dto.setReturnmoney(returnmoney);
			dto.setBetflag(betflag);
			dto.setCreatetime(createtime);
			dto.setUpdatetime(updatetime);
			dto.setCreateip(createip);
			dto.setUpdateip(updateip);
			dto.setUsername(username);
			list.add(dto);
		}
		return list;
	}

	@Override
	public List<BetDTO> list(BetForm betForm)
			throws DataAccessException {
		// TODO Auto-generated method stub
		ResultSet rs = null;
		PreparedStatement ps = null;
		List<BetDTO> list = null;
		StringBuilder sb = new StringBuilder();
		String userName = betForm.getUserName();
		String betMethod = betForm.getBetMethod();
		String gameType = betForm.getGameType();
		String betType = betForm.getBetType();
		String betflag = betForm.getBetFlag();
		String startTime = betForm.getStartTime();
		String endTime = betForm.getEndTime();
		int currentPage = 1;
		int pageSize = Constants.ADM_RECORD_PER_PAGE;
		List<String> parameterValues = new ArrayList<String>();
		List<Integer> parameterTypes = new ArrayList<Integer>();
		try{
			currentPage = Integer.parseInt(betForm.getCurrentPage());
		}catch(Exception e){
			logError(e);
		}
		if(null != userName && userName.length() > 0){
			sb.append(" and b.username like ? ");
			parameterValues.add("%" + userName + "%");
			parameterTypes.add(Types.VARCHAR);
		}
		if(null != betMethod && betMethod.length() > 0){
			sb.append(" and a.betMethod =? ");
			parameterValues.add(betMethod);
			parameterTypes.add(Types.VARCHAR);
		}
		if(null != gameType && gameType.length() > 0){
			sb.append(" and a.gametype =? ");
			parameterValues.add(gameType);
			parameterTypes.add(Types.VARCHAR);
		}
		if(null != betType && betType.length() > 0){
			sb.append(" and a.bettype =? ");
			parameterValues.add(betType);
			parameterTypes.add(Types.VARCHAR);
		}
		if(null != betflag && betflag.length() > 0){
			sb.append(" and a.betflag =? ");
			parameterValues.add(betflag);
			parameterTypes.add(Types.VARCHAR);
		}
		if(null != startTime && startTime.length() > 0){
			sb.append(" and a.createtime >=? ");
			parameterValues.add(startTime + " 00:00:00");
			parameterTypes.add(Types.VARCHAR);
		}
		if(null != endTime && endTime.length() > 0){
			sb.append(" and a.createtime <=? ");
			parameterValues.add(endTime + " 23:59:59");
			parameterTypes.add(Types.VARCHAR);
		}
		
		try {
			//总记录查询
			_builder = (PreparedStatementBuilder) SqlLoader.getBuilders().get("ADM_BetDAO_SELECT_TOTAL_COUNT");
			String totalSQL = _builder.getSql(null, null) + sb.toString();
			ps = _builder.createStatement(_conn, totalSQL, false, false);
			fillParameters(_builder,ps,parameterValues,parameterTypes);
			debugSql();
			rs = ps.executeQuery();
			int totalRecord = 0;
			if(rs.next()){
				totalRecord = rs.getInt(1);
			}
			if(null != rs){
				rs.close();
			}
			if(null != ps){
				ps.close();
			}
			if(totalRecord <= 0){
				return list;
			}
			
			//分页查询记录
			sb.append(" order by a.createtime desc ");
			_builder = (PreparedStatementBuilder) SqlLoader.getBuilders().get("ADM_BetDAO_SELECT");
			int totalPage = 0;
			if(totalRecord % pageSize == 0){
				totalPage = totalRecord / pageSize;
			}else{
				totalPage = totalRecord / pageSize + 1;
			}
			if(currentPage <= 0){
				currentPage = 1;
			}else if (currentPage > totalPage){
				currentPage = totalPage;
			}
			String hasPrevious = "false";
			String hasNext = "false";
			if(currentPage > 1){
				hasPrevious = "true";
			}
			if(currentPage < totalPage){
				hasNext = "true";
			}
			String limitSQL = _builder.getSql(null, null) + sb.toString() + " limit " + ((currentPage-1)*pageSize) + "," + pageSize;
			ps = _builder.createStatement(_conn, limitSQL, false, false);
			fillParameters(_builder,ps,parameterValues,parameterTypes);
			debugSql();
			rs = ps.executeQuery();
			list = toList(rs);
			
			betForm.setCurrentPage(new Integer(currentPage).toString());
			betForm.setFirstPage("1");
			betForm.setHasPrevious(hasPrevious);
			betForm.setHasNext(hasNext);
			betForm.setNextPage(new Integer(currentPage + 1).toString());
			betForm.setPreviousPage(new Integer(currentPage - 1).toString());
			betForm.setTotalPage(new Integer(totalPage).toString());
			betForm.setTotalRecord(new Integer(totalRecord).toString());
		} catch (Exception e) {
			errorSql(e);
			_exHandler.handleQueryException(e, ExceptionHandler.UNKNOWN);
		} finally {
			try {
				if (null != rs) {
					rs.close();
				}
				if (null != ps) {
					ps.close();
				}
				if(null != _conn){
					_conn.close();
				}
			} catch (SQLException e) {
				logError(e);
			}
		}
		return list;
	}
	
	private void fillParameters(PreparedStatementBuilder builder,PreparedStatement ps,List<String> parameterValues,List<Integer> parameterTypes) throws Exception{
		if(null != parameterValues && parameterValues.size() >0){
			for(int i = 0 ;i < parameterValues.size() ; i ++){
				int type = Integer.parseInt(parameterTypes.get(i).toString());
				builder.setParameter(ps, (i + 1), parameterValues.get(i) , type);
			}
		}
	}

	@Override
	public BetDTO getBetByID(String id) throws DataAccessException {
		// TODO Auto-generated method stub
		BetDTO dto = null ;
		ResultSet rs = null;
		PreparedStatement ps = null;
		try {
			_builder = (PreparedStatementBuilder) SqlLoader.getBuilders().get("ADM_BetDAO_GET_BET_RECORD");
			String sql = _builder.getSql(null, null);
			ps = _builder.createStatement(_conn, sql, false, false);
			_builder.setParameter(ps, 1, id , Types.VARCHAR);
			debugSql();
			rs = ps.executeQuery();
			if(rs.next()){
				String betid = getString(rs.getString(field.betid.ordinal()+1));
				String uid = getString(rs.getString(field.userid.ordinal()+1));
				int betmethod = rs.getInt(field.betmethod.ordinal()+1);
				String types = rs.getString(field.types.ordinal()+1);
				String gametype = rs.getString(field.gametype.ordinal()+1);
				String gametypename = rs.getString(field.gametypename.ordinal()+1);
				String bettype = rs.getString(field.bettype.ordinal()+1);
				String bettypename = rs.getString(field.bettypename.ordinal()+1);
				double betmoney = rs.getDouble(field.betmoney.ordinal()+1);
				double bonus = rs.getDouble(field.bonus.ordinal()+1);
				String betstr = rs.getString(field.betstr.ordinal()+1);
				String betstrs = rs.getString(field.betstrs.ordinal()+1);
				int betcount = rs.getInt(field.betcount.ordinal()+1);
				double singlemoney = rs.getDouble(field.singlemoney.ordinal()+1);
				String betno = rs.getString(field.betno.ordinal()+1);
				String opentime = rs.getString(field.opentime.ordinal()+1);
				double returnpos = rs.getDouble(field.returnpos.ordinal()+1);
				double returnmoney = rs.getDouble(field.returnmoney.ordinal()+1);
				int betflag = rs.getInt(field.betflag.ordinal()+1);
				String createtime = rs.getString(field.createtime.ordinal()+1);
				String updatetime = rs.getString(field.updatetime.ordinal()+1);
				String createip = getString(rs.getString(field.createip.ordinal()+1));
				String updateip = getString(rs.getString(field.updateip.ordinal()+1));
				String username = getString(rs.getString(field.username.ordinal()+1));
				dto = new BetDTO();
				dto.setBetid(betid);
				dto.setUserid(uid);
				dto.setBetmethod(betmethod);
				dto.setTypes(types);
				dto.setGametype(gametype);
				dto.setGametypename(gametypename);
				dto.setBettype(bettype);
				dto.setBettypename(bettypename);
				dto.setBetmoney(betmoney);
				dto.setBonus(bonus);
				dto.setBetstr(betstr);
				dto.setBetstrs(betstrs);
				dto.setBetcount(betcount);
				dto.setSinglemoney(singlemoney);
				dto.setBetno(betno);
				dto.setOpentime(opentime);
				dto.setReturnpos(returnpos);
				dto.setReturnmoney(returnmoney);
				dto.setBetflag(betflag);
				dto.setCreatetime(createtime);
				dto.setUpdatetime(updatetime);
				dto.setCreateip(createip);
				dto.setUpdateip(updateip);
				dto.setUsername(username);
			}
		} catch (Exception e) {
			errorSql(e);
			_exHandler.handleQueryException(e, ExceptionHandler.UNKNOWN);
		} finally {
			try {
				if (null != rs) {
					rs.close();
				}
				if (null != ps) {
					ps.close();
				}
				if(null != _conn){
					_conn.close();
				}
			} catch (SQLException e) {
				logError(e);
			}
		}
		return dto;
	}
}
